﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="TestClearColumn.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.Tests.RMDenseMatrixTest
{
    #region Usings

    using System;
    using System.Diagnostics.CodeAnalysis;

    using ExulLibrary.Exceptions;

    using NUnit.Framework;

    #endregion

    /// <summary>
    ///     Test suite for <see cref="RMDenseMatrixExtensions.ClearColumn{T}"/>.
    /// </summary>
    [TestFixture]
    [Category("ExulLibrary.Mathematics.LinearAlgebra.Sequential.RMDenseMatrix1DSExtensions")]
    public sealed class TestClearColumn
    {
        /// <summary>
        ///     Tests the method when column index is non-negative and less than columns count.
        /// </summary>
        /// <param name="columnIndex">
        ///     The index of the column.
        /// </param>
        [SuppressMessage(
            "Microsoft.Usage",
            "CA2233:OperationsShouldNotOverflow",
            MessageId = "columnIndex+1",
            Justification = "Division with remainder doesn't produce overflow")]
        [SuppressMessage(
            "Microsoft.Usage",
            "CA2233:OperationsShouldNotOverflow",
            MessageId = "columnIndex+2",
            Justification = "Division with remainder doesn't produce overflow")]
        [Test]
        public void WhenColumnIndexIsValid([Values(0, 1, 2)] int columnIndex)
        {
            // Arrange
            const int ColumnsCount = 3;
            var data = new[]
                       {
                           new[] { new object(), new object(), new object() },
                           new[] { new object(), new object(), new object() }
                       };

            var instance = new RMDenseMatrix<object>(data);

            // Act
            instance.ClearColumn(columnIndex);

            // Assert
            Assert.That(instance.Values[0][columnIndex], Is.Null);
            Assert.That(instance.Values[1][columnIndex], Is.Null);

            Assert.That(instance.Values[0][(columnIndex + 1) % ColumnsCount], Is.Not.Null);
            Assert.That(instance.Values[1][(columnIndex + 1) % ColumnsCount], Is.Not.Null);
            Assert.That(instance.Values[0][(columnIndex + 2) % ColumnsCount], Is.Not.Null);
            Assert.That(instance.Values[1][(columnIndex + 2) % ColumnsCount], Is.Not.Null);
        }

#if SAFE

        /// <summary>
        ///     Tests the method when column index is negative or greater than or equal to columns count.
        /// </summary>
        /// <param name="columnIndex">
        ///     Index of the column.
        /// </param>
        [Test]
        public void WhenColumnIndexIsOutOfRange([Values(-1, 3)] int columnIndex)
        {
            // Arrange
            var data = new[]
                       {
                           new object[3],
                           new object[3],
                           new object[3],
                           new object[3]
                       };
            var instance = new RMDenseMatrix<object>(data);

            // Act and Assert
            Assert.That(
                () => instance.ClearColumn(columnIndex),
                Throws.TypeOf<ElementIndexIsOutOfRangeException>().With.Property("ParamName").EqualTo("columnIndex"));
        }

        /// <summary>
        ///     Tests the method when matrix parameter is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenMatrixIsNull()
        {
            // Act and Assert
            Assert.That(
                () => RMDenseMatrixExtensions.ClearColumn<object>(null, 0),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("matrix"));
        }

#endif
    }
}